package com.credithc.signature.manager.cron;

import com.credithc.signature.common.mapper.CallChannelHourMapper;
import com.credithc.signature.common.mapper.CallHourMapper;
import com.credithc.signature.common.mapper.CallStatisticsMapper;
import com.credithc.signature.common.mapper.RequestLogMapper;
import com.credithc.signature.common.mapper.TemplateMapper;
import com.credithc.signature.common.po.CallChannelHour;
import com.credithc.signature.common.po.CallHour;
import com.credithc.signature.common.po.CallStatistics;
import com.credithc.signature.common.po.SealApplyInfoDTO;
import com.credithc.signature.common.po.Template;
import com.credithc.signature.common.service.TemplateService;
import com.credithc.signature.common.utils.DateUtil;
import com.credithc.signature.common.utils.TimeUtil;
import com.credithc.signature.manager.service.StatisticsSerivce;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Component
@Async
public class StatisticsCron {

    @Autowired
    private StatisticsSerivce statisticsSerivce;

    @Autowired
    private RequestLogMapper requestLogMapper;

    @Autowired
    private CallStatisticsMapper callStatisticsMapper;

    @Autowired
    private CallChannelHourMapper callChannelHourMapper;

    @Autowired
    private CallHourMapper callHourMapper;

    @Autowired
    TemplateService templateService;

    @Resource(name = "masterJdbcTemplate")
    JdbcTemplate masterJdbcTemplate;

    @Resource(name = "salveJdbcTemplate")
    JdbcTemplate salveJdbcTemplate;

    /**
     * 每天凌晨执行一次
     * 插入小时调用表当天所有的数据
     */
    @Scheduled(cron = "0 0 0 * * ?")
    public void callHour() {
        log.info("执行定时任务 插入每天小时统计时间id 每天执行一次 现在时间为" + new Date());
        statisticsSerivce.bulidDayDate();
    }

    /**
     * 每天凌晨执行一次
     * 插入小时渠道调用表当天所有的数据
     */
    @Scheduled(cron = "0 0 0 * * ?")
    //@Scheduled(cron = "0 26 11 ? * *")
    public void callChannelHour() {
        log.info("执行定时任务 插入每天渠道小时统计时间id 每天执行一次 现在时间为" + new Date());
        statisticsSerivce.bulidDayDate("");
    }

    @Scheduled(cron = "0 0 0/1 * * ?")
    public void statisticsNum() {
        log.info("执行定时任务 统计调用数量插入对应表中 每小时执行一次 现在时间为" + new Date());
        Timestamp time = new Timestamp(System.currentTimeMillis());
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHH");
        String timeId = format.format(new Date());
        Timestamp beforeTime = new Timestamp(System.currentTimeMillis() - 60 * 60 * 1000);
        List<CallChannelHour> callChannelHours = requestLogMapper.StatisticsByTimeGropByChannel(time, beforeTime);
        int sum = 0;
        for (CallChannelHour c : callChannelHours) {
            Example example = new Example(CallChannelHour.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("channelNo", c.getChannelNo());
            criteria.andEqualTo("timeId", timeId);
            CallChannelHour callChannelHour = new CallChannelHour();
            callChannelHour.setNum(c.getNum());
            callChannelHourMapper.updateByExampleSelective(callChannelHour, example);
            sum += c.getNum();
        }
        if (sum > 0) {
            Example example = new Example(CallHour.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("timeId", timeId);
            CallHour callHour = new CallHour();
            callHour.setNum(sum);
            callHourMapper.updateByExampleSelective(callHour, example);
        }
    }

    /**
     * 每天凌晨执行一次
     * 插入统计表成功与失败的数量
     */
    @Scheduled(cron = "0 0 0 * * ?")
    public void statistics() {
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        String timeId = format.format(TimeUtil.yesterday(new Date()));
        statisticsSerivce.bulidChannelDayDate(timeId);
        log.info("执行定时任务 统计调用成功失败数量插入对应表中 每天执行一次 现在时间为" + new Date());
        Timestamp time = new Timestamp(System.currentTimeMillis());
        Timestamp beforeTime = new Timestamp(System.currentTimeMillis() - 60 * 60 * 24 * 1000);
        List<CallStatistics> callStatistics = new ArrayList<>();
        bulidbeforeDayDate(2, timeId, time, beforeTime, callStatistics);
        bulidbeforeDayDate(3, timeId, time, beforeTime, callStatistics);
    }

    private void bulidbeforeDayDate(Integer status, String timeId, Timestamp time, Timestamp beforeTime, List<CallStatistics> callStatistics) {
        try {
            callStatistics = requestLogMapper.selectCountByStatusGroupByChannel(status, time, beforeTime);
        } catch (Exception e) {
            log.info("方法[bulidbeforeDayDate]统计失败", e);
        }
        if (status == 2) {
            status = 0;
        } else {
            status = 1;
        }
        int successNum = 0;
        for (CallStatistics c : callStatistics) {
            Example example = new Example(CallStatistics.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("timeId", timeId);
            criteria.andEqualTo("status", status);
            criteria.andEqualTo("channelNo", c.getChannelNo());
            c.setTimeId(timeId);
            c.setStatus(status);
            try {
                callStatisticsMapper.updateByExampleSelective(c, example);
            } catch (Exception e) {
                log.error("更新统计数量出错", e);
            }
            successNum += c.getNum();
        }
        CallStatistics callStatistics1 = new CallStatistics();
        callStatistics1.setTimeId(timeId);
        callStatistics1.setStatus(status);
        callStatistics1.setChannelNo("0");
        callStatistics1.setNum(successNum);
        callStatisticsMapper.insert(callStatistics1);
    }

    /**
     * 每三分钟执行一次
     * 删除重复数据
     */
    @Scheduled(cron = "0 */3 * * * ?")
    public void zj() {
        Template qz2020CSZHzj101 = templateService.selectByTemplateNo("QZ2020CSZHzj101");
        if (qz2020CSZHzj101 != null && qz2020CSZHzj101.getVip() == 1) {
            // 删除3分钟之前的错误数据
            log.info("执行定时任务，删除seal_apply_info表异常数据......");
            String beforeMinute = DateUtil.getBeforeMinute(3);
            String querySql = "SELECT id from SEAL_APPLY_INFO WHERE CREATE_TIME <= '" + beforeMinute + "' AND SEAL_CODE NOT IN ( SELECT `CODE` FROM SEAL );";
            List<SealApplyInfoDTO> query = salveJdbcTemplate.query(querySql, new BeanPropertyRowMapper<>(SealApplyInfoDTO.class));
            List<String> ids = query.stream().map(SealApplyInfoDTO::getId).collect(Collectors.toList());
            if (ids != null && ids.size() > 0) {
                log.info("定时任务删除seal_apply_info表数据,ids={}", ids.toString());
                for (String id : ids) {
                    String removeSql = "DELETE FROM SEAL_APPLY_INFO WHERE id = '" + id + "'";
                    masterJdbcTemplate.update(removeSql);
                    log.info("删除成功ID=【{}】数据", id);
                }
            }
        }
    }
}
